﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynaPrecision.LinearSystem
{
	/// <summary>
	/// 
	/// </summary>
	/// <typeparam name="T"></typeparam>
	[Serializable]
	public class MultiDimensionalArray<T> : IInitializableArray<T>
	{
		public MultiDimensionalArray()
		{
		}
		public MultiDimensionalArray(params int[] lengths)
		{
			Initiate(lengths);
		}
		private List<T> _storage;
		private List<int> TotalCountForEachDimension
		{
			get
			{
				List<int> result = new List<int>(ListGenerator.ConstantValueList<int>(1, Lengths.Count));
				for (int i = Lengths.Count - 2; i >= 0; i--)
				{
					result[i] = result[i + 1] * Lengths[i + 1];
				}
				return result;
			}
		}
		public int TotalCount
		{
			get
			{
				int result = 1;
				foreach (int i in Lengths)
				{
					result *= i;
				}
				return result;
			}
		}
		public IList<T> Storage
		{
			get
			{
				return _storage;
			}
		}
		public List<int> Lengths { get; set; }
		private int _translatePosition(params int[] index)
		{
			int result = 0;
			for (int i = 0; i < index.Length && i < TotalCountForEachDimension.Count; i++)
			{
				result += index[i] * TotalCountForEachDimension[i];
			}
			return result;
		}
		#region IMultiDimensionalArray<T> Members

		public T this[params int[] index]
		{
			get
			{
				return _storage[_translatePosition(index)];
			}
			set
			{
				_storage[_translatePosition(index)] = value;
			}
		}

		public int GetLength(int DimensinNumber)
		{
			if (DimensinNumber < Lengths.Count)
			{
				return Lengths[DimensinNumber];
			}
			else
			{
				return 0;
			}
		}

		public int Dimension
		{
			get
			{
				return Lengths.Count;
			}
		}
		#endregion

		#region IInitializableArray<T> Members

		public void Initiate(params int[] lengths)
		{
			this.Lengths = lengths.ToList();
			_storage = new List<T>(ListGenerator.ConstantValueList<T>(default(T), TotalCount));
		}

		#endregion
	}
}